package com.atguigu.gmall.order.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.model.cart.CartInfo;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.model.user.UserAddress;
import com.atguigu.gmall.mq.mqconst.MqWareConst;
import com.atguigu.gmall.mq.service.RabbitService;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.atguigu.gmall.user.clinet.UserFeignClient;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional(readOnly = false)
public class OrderServiceImpl implements OrderService {

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private UserFeignClient userFeignClient;

    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RabbitService rabbitService;


    @Override
    public Map<String, Object> trade(String userId) {
        Map<String, Object> resultMap = new HashMap<>();
        List<CartInfo> cartDataList = cartFeignClient.getCheckedCart().getData();
        List<OrderDetail> orderDetailList = cartDataList.stream()
                .map(cartInfo -> {
                    OrderDetail orderDetail = new OrderDetail();
                    BeanUtils.copyProperties(cartInfo, orderDetail);
                    orderDetail.setOrderPrice(cartInfo.getSkuPrice());
                    return orderDetail;
                }).collect(Collectors.toList());

        Integer totalNum = cartDataList.stream()
                .map(cartInfo -> cartInfo.getSkuNum())
                .reduce(0, (x, y) -> {
                    return x + y;
                });
        Double totalAmount = cartDataList.stream()
                .map(cartInfo -> cartInfo.getSkuNum() * cartInfo.getSkuPrice().doubleValue())
                .reduce((double) 0, (x, y) -> {
                    return x + y;
                });
        List<UserAddress> userAddressList = userFeignClient.getUserAddressList().getData();
        resultMap.put("detailArrayList", orderDetailList);
        resultMap.put("totalNum", totalNum);
        resultMap.put("totalAmount", totalAmount);
        resultMap.put("userAddressList", userAddressList);
        return resultMap;
    }

    @Override
    @Transactional(readOnly = false,rollbackFor = Exception.class)
    public Long saveOrder(OrderInfo orderInfo, String userId) {
        String tradeNo ="MUCH_MONEY_"+  userId+"_"+System.currentTimeMillis() + new Random().nextInt(1000);
        orderInfo.setOutTradeNo(tradeNo);
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        StringBuilder sb = new StringBuilder();
        for (OrderDetail orderDetail : orderDetailList) {
            String skuName = orderDetail.getSkuName();
            sb.append(skuName).append(",");
        }
        String strOrderName = sb.toString();
        String tradeBody = strOrderName.substring(0, strOrderName.length() - 1);
        if (tradeBody.length() > 150) {
            tradeBody = tradeBody.substring(0, 150);
        }
        orderInfo.setTradeBody(tradeBody);

        orderInfo.sumTotalAmount();

        orderInfo.setOrderStatus(OrderStatus.UNPAID.toString());

        orderInfo.setProcessStatus(ProcessStatus.UNPAID.toString());

        orderInfo.setUserId(Long.parseLong(userId));

        orderInfo.setCreateTime(new Date());

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, 1);
        orderInfo.setExpireTime(calendar.getTime());

        orderInfoMapper.insert(orderInfo);

        Long orderInfoId = orderInfo.getId();
        List<OrderDetail> orderDetailListSave = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailListSave) {
            orderDetail.setOrderId(orderInfoId);
            orderDetailMapper.insert(orderDetail);
        }

        //todo 清空购物车
        return orderInfoId;

    }

    @Override
    public OrderInfo getOrderById(Long orderId) {

        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        return orderInfo;
    }

    @Override
    public OrderInfo getOrderInfoByOutTradeNo(String outTradeNo) {
        return orderInfoMapper.selectOne(new QueryWrapper<OrderInfo>().eq("out_trade_no", outTradeNo));
    }

    @Override
    public void saveOrderById(OrderInfo orderInfo) {
        orderInfoMapper.updateById(orderInfo);
    }

    @Override
    public void notifyWareSystemToDeliver(Long orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectOderInfoAndOrderDetail(orderId);
        String orderInfoJson = buildOrderInfoJson(orderInfo);
        rabbitService.sendMessage(MqWareConst.EXCHANGE_WARE, MqWareConst.ROUTING_KEY_WARE, orderInfoJson);
    }

    @Override
    public void updateOrderStatus(String orderId, String orderStatus, String processStatus) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(Long.parseLong(orderId));
        orderInfo.setOrderStatus(orderStatus);
        orderInfo.setProcessStatus(processStatus);
        orderInfoMapper.updateById(orderInfo);
    }

    public String buildOrderInfoJson(OrderInfo orderInfo) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderId", orderInfo.getId());
        jsonObject.put("consignee", orderInfo.getConsignee());
        jsonObject.put("consigneeTel", orderInfo.getConsigneeTel());
        jsonObject.put("orderComment", orderInfo.getOrderComment());
        jsonObject.put("orderBody", orderInfo.getTradeBody());
        jsonObject.put("deliveryAddress", orderInfo.getDeliveryAddress());
        String paymentWay = orderInfo.getPaymentWay();
        if ("ONLINE".equals(paymentWay)) {
            jsonObject.put("paymentWay", "2");
        }else{
            jsonObject.put("paymentWay", "1");
        }


        ArrayList<JSONObject> jsonObjectArrayList = new ArrayList<>();
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        for (OrderDetail orderDetail : orderDetailList) {
            JSONObject orderDetailJsonObject = new JSONObject();
            orderDetailJsonObject.put("skuId", orderDetail.getOrderId());
            orderDetailJsonObject.put("skuName", orderDetail.getSkuName());
            orderDetailJsonObject.put("skuNum", orderDetail.getSkuNum());

            jsonObjectArrayList.add(orderDetailJsonObject);
        }
        jsonObject.put("details",jsonObjectArrayList);
        return jsonObject.toJSONString();
    }
}
